package com.von.aspect;

import cn.hutool.json.JSONUtil;
import com.von.entity.ThrowingLog;
import com.von.mapper.ThrowingLogMapper;
import com.von.utils.IpInfoUtil;
import com.von.utils.ThreadPoolUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;


@Aspect
@Component
@Slf4j
public class ThrowingAspect {

    @Autowired
    private ThrowingLogMapper throwingLogMapper;

    @Autowired
    private IpInfoUtil ipInfoUtil;

    @Autowired(required = false)
    private HttpServletRequest request;

    @Pointcut("execution(* com.von.controller..*.*(..))")
    public void throwingAspect() {
    }

    @AfterThrowing(pointcut = "throwingAspect()", throwing = "throwinfo")
    public void throwafter(JoinPoint joinPoint, Throwable throwinfo) {
        ThrowingLog throwingLog = new ThrowingLog();
        throwingLog.setRequestUrl(request.getRequestURI());
        //请求方式
        throwingLog.setRequestType(request.getMethod());
        //请求参数
        throwingLog.setRequestParam(JSONUtil.toJsonStr(joinPoint.getArgs()));
        //其他属性
        throwingLog.setIp(ipInfoUtil.getIpAddr(request));
        throwingLog.setThrowing(throwinfo.getMessage());
        ThreadPoolUtil.getPool().execute(new ThrowingAspect.SaveThrowingLogThread(throwingLog, throwingLogMapper));
    }

    private static class SaveThrowingLogThread implements Runnable {

        private ThrowingLog log;

        private ThrowingLogMapper throwingLogMapper;

        public SaveThrowingLogThread(ThrowingLog esLog, ThrowingLogMapper throwingLogMapper) {
            this.log = esLog;
            this.throwingLogMapper = throwingLogMapper;
        }

        @Override
        public void run() {
            throwingLogMapper.insert(log);
        }
    }
}
